#include "etelonny.hxx"
#include <algorithm>
#include <iostream>

void etelonny::sobel_dx(short *source, short *dist, int xcount, int ycount, int zcount)
{
    //dx
    for (int y = 0; y < ycount * zcount * xcount; y += xcount)
    {
        dist[y] = (source[y + 1] - source[y]) >> 1;
        dist[y + xcount - 1] = (source[y + xcount - 1]- source[y + xcount - 2]) >> 1;

        for (int x = y + 1; x < y + xcount - 1; x++)
        {
            dist[x]  = (source[x + 1] - source[x - 1]) >> 1;
        }
    }
    
    std::swap(source, dist);

    //dy
    for (int tag = 0; tag < xcount * ycount * zcount; tag += ycount * xcount)
    {
        for (int x = tag; x < tag + xcount; x++)
        {
            dist[x]  = (3 * source[x] + source[x + xcount]) >> 2;
        }

        for (int x = tag + xcount; x < tag + xcount * (ycount - 1); x++)
        {
            dist[x]  = (2 * source[x] + source[x - xcount] + source[x + xcount]) >> 2;
        }

        for (int x = tag + xcount * (ycount-1); x < tag + xcount * ycount; x++)
        {
            dist[x]  = (3 * source[x] + source[x - xcount]) >> 2;
        }
    }
    
    std::swap(source, dist);

    //dz
    for (int x = 0; x < xcount * ycount; x++)
    {
        dist[x]  = (3 * source[x] + source[x + ycount * xcount]) >> 2;
        dist[xcount * ycount * (zcount - 1) + x] = (3 * source[xcount * ycount * (zcount - 1) + x] + source[xcount * ycount * (zcount - 2) + x]) >> 2;
    }

    for (int tag = xcount * ycount; tag < ycount * (zcount - 1)* xcount; tag += ycount * xcount)
    {
        for(int x = tag; x < tag + xcount * ycount; x++)
        {
            dist[x]  = (2 * source[x] + source[x - (ycount * xcount)] + source[x + (ycount * xcount)]) >> 2;
        }
    }
}

bool etelonny::compare(short *source, short *dist,int count)
{
    int sum = 0;
    for (int i = 0; (i < count) && (sum < 512) ; i++)
    {
        if (std::abs(source[i] - dist[i]) >= 2)
        {
            std::cout << "given " << source[i] << " expected " << dist[i] << " index " << i << std::endl;
            sum++;
        }
    }
    if (sum > 512) std::cout << "and more on......" << std::endl;
    std::cout << "The sum of not closed elements is " <<  sum << std::endl;
    if(sum) return false; 
    return true;
}

bool etelonny::zero(short *source, int count)
{
    for(int i = 0; i < count; i++)
    {
        if(source[i] != 0)
            return false;
    }
    return true;
}